import { Response } from 'express';
import { AuthenticatedRequest } from '../types';
import EvaluationModel from '../models/evaluationModel';
import StudentModel from '../models/studentModel';
import { AnalysisConfig } from '../config/analysisConfig';

interface PredictionResult {
  predictedScore: number;
  confidenceInterval: {
    min: number;
    max: number;
  };
  riskLevel: 'low' | 'medium' | 'high';
  recommendations: string[];
}

export const getLearningPrediction = async (req: AuthenticatedRequest, res: Response): Promise<void> => {
  try {
    const { studentId } = req.params;

    // 获取学生信息
    const student = await StudentModel.findById(studentId);
    if (!student) {
      res.status(404).json({ message: '学生不存在' });
      return;
    }

    // 获取历史评分数据
    const evaluations = await EvaluationModel.find({ studentId })
      .sort('-createdAt')
      .limit(AnalysisConfig.algorithms.prediction.minDataPoints);

    if (evaluations.length < AnalysisConfig.algorithms.prediction.minDataPoints) {
      res.status(400).json({
        message: '历史数据不足，无法生成预测'
      });
      return;
    }

    // 分析历史分数趋势
    const scores = evaluations.map(e => e.score).filter((score): score is number => score !== undefined);

    if (scores.length === 0) {
      res.status(400).json({
        message: '没有有效的评分数据用于预测'
      });
      return;
    }
    const trend = calculateTrend(scores);
    
    // 计算预测分数
    const latestScore = scores[0];
    const predictedScore = Math.min(100, Math.max(0, latestScore + trend));
    
    // 计算置信区间
    const standardDeviation = calculateStandardDeviation(scores);
    const confidenceInterval = {
      min: Math.max(0, predictedScore - 1.96 * standardDeviation),
      max: Math.min(100, predictedScore + 1.96 * standardDeviation)
    };

    // 评估风险等级
    const riskLevel = assessRiskLevel(predictedScore, standardDeviation);

    // 生成建议
    const recommendations = generateRecommendations(predictedScore, riskLevel, trend);

    const result: PredictionResult = {
      predictedScore,
      confidenceInterval,
      riskLevel,
      recommendations
    };

    res.json(result);
  } catch (error) {
    res.status(500).json({ message: '生成学习预测失败', error });
  }
};

// 计算分数趋势
function calculateTrend(scores: number[]): number {
  if (scores.length < 2) return 0;
  
  const n = scores.length;
  let sumX = 0;
  let sumY = 0;
  let sumXY = 0;
  let sumXX = 0;
  
  for (let i = 0; i < n; i++) {
    sumX += i;
    sumY += scores[i];
    sumXY += i * scores[i];
    sumXX += i * i;
  }
  
  const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
  return slope;
}

// 计算标准差
function calculateStandardDeviation(scores: number[]): number {
  const n = scores.length;
  const mean = scores.reduce((a, b) => a + b, 0) / n;
  const variance = scores.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / n;
  return Math.sqrt(variance);
}

// 评估风险等级
function assessRiskLevel(predictedScore: number, standardDeviation: number): 'low' | 'medium' | 'high' {
  if (predictedScore >= 80 && standardDeviation < 5) {
    return 'low';
  } else if (predictedScore >= 60 || standardDeviation < 10) {
    return 'medium';
  } else {
    return 'high';
  }
}

// 生成建议
function generateRecommendations(
  predictedScore: number,
  riskLevel: 'low' | 'medium' | 'high',
  trend: number
): string[] {
  const recommendations: string[] = [];

  // 基于预测分数的建议
  if (predictedScore >= 90) {
    recommendations.push('继续保持优秀的学习状态');
    recommendations.push('可以尝试更具挑战性的题目');
  } else if (predictedScore >= 80) {
    recommendations.push('成绩良好，建议关注细节提高准确度');
    recommendations.push('适当增加练习难度');
  } else if (predictedScore >= 60) {
    recommendations.push('需要加强基础知识的巩固');
    recommendations.push('增加练习频率，提高熟练度');
  } else {
    recommendations.push('建议系统性复习基础知识');
    recommendations.push('制定针对性的学习计划');
    recommendations.push('可以寻求老师的辅导帮助');
  }

  // 基于趋势的建议
  if (trend > 0) {
    recommendations.push('学习进步明显，继续保持');
  } else if (trend < 0) {
    recommendations.push('近期成绩有所下滑，需要及时调整');
  }

  // 基于风险等级的建议
  switch (riskLevel) {
    case 'high':
      recommendations.push('建议立即进行知识点诊断');
      recommendations.push('制定详细的提升计划');
      break;
    case 'medium':
      recommendations.push('关注薄弱环节，及时查漏补缺');
      break;
    case 'low':
      recommendations.push('可以尝试拓展学习内容');
      break;
  }

  return recommendations;
}
